using System.Collections.Generic;
using GeneticAlgorithms.Genomes;

namespace GeneticAlgorithms.Operators.Mating
{
    /// <summary>
    /// A simple genome mater that will return genomes in pairs.
    /// </summary>
    /// <typeparam name="TGenome">The type of the genome.</typeparam>
    /// <typeparam name="TGene">The type of the gene.</typeparam>
    public class SimpleMater<TGenome, TGene> : IGeneticMater<TGenome, TGene>
        where TGenome : IGenome<TGene>
    {
        #region IGeneticMater<TGene> Members

        /// <summary>
        /// Gets the cardinality of the mating operation.
        /// </summary>
        /// <value>
        /// The cardinality of the mating operation:
        /// that is, how many genomes a mating will put
        /// together at each step.
        /// </value>
        public int Cardinality
        {
            get { return 2; }
        }

        /// <summary>
        /// Mates the specified genomes.
        /// </summary>
        /// <param name="genomes">The genomes to be agrouped in pairs.</param>
        /// <returns>
        /// A genome of aggrouped genomes. Each group represents a mating set.
        /// </returns>
        public IEnumerable<TGenome[]> Mate(IEnumerable<TGenome> genomes)
        {
            TGenome[] pair = new TGenome[2];
            int pos = 0;

            foreach (TGenome genome in genomes)
            {
                pair[pos] = genome;
                if (pos > 0)
                {
                    pos = 0;
                    yield return pair;
                }
                else
                {
                    pos++;
                }
            }            
        }

        #endregion
    }
}
